package de.bensoft.jrail.client.com;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

import org.apache.log4j.Logger;

import de.bensoft.jrail.business.entity.Locomotive;
import de.bensoft.jrail.client.com.interfaces.LI100;

public class TrainInstance {

	private static final Logger log = Logger.getLogger(TrainInstance.class);
		
	private TrainCommunicator communicator;
	
	private LongProperty speedProperty;
	public LongProperty speedProperty() { return speedProperty; }
	
	private BooleanProperty lightProperty;
	public BooleanProperty lightProperty() { return lightProperty; }
	
	private BooleanProperty driveForwardProperty;
	public BooleanProperty driveForwardProperty() { return driveForwardProperty; }
	
	
	
	private Locomotive locomotive;
	public Locomotive getLocomotive() { return locomotive; }
	public void setLocomotive(Locomotive locomotive) { this.locomotive = locomotive; }
	
	
	
	public TrainInstance(final TrainCommunicator communicator, Locomotive locomotive) {
		this.communicator = communicator;
		this.locomotive = locomotive;
		
		speedProperty = new SimpleLongProperty();
		speedProperty.addListener(new ChangeListener<Number>() {

			public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
				sendSpeedAndDirection();
			}	
		});
		
		
		lightProperty = new SimpleBooleanProperty();
		lightProperty.addListener(new ChangeListener<Boolean>() {
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
				
				String onoff = "on";
				if(arg2 != null && arg2.equals(Boolean.FALSE))
					onoff = "off";
				
				log.info("[" + getLocomotive().getName() + "] Light turned " + onoff);
				sendFunctionGroup1();
			}		
		});	
		
		driveForwardProperty = new SimpleBooleanProperty(true);
		driveForwardProperty.addListener(new ChangeListener<Boolean>() {
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
				sendSpeedAndDirection();		
			}		
		});
	}
	
	
	private void sendSpeedAndDirection() {
		log.info("[" + getLocomotive().getName() + "] Train speed set to " + speedProperty.longValue());
		
		
		byte[] cmd = LI100.buildTrainSpeedCommand(getLocomotive().getSpeedSteps(),
												  getLocomotive().getAddress(),
												  driveForwardProperty.get(), 
												  Math.abs(speedProperty.longValue()));
		
		communicator.sendCommand(cmd);
	}
	
	private void sendFunctionGroup1() {
		byte[] cmd = LI100.buildFunctionStateCommandGroup1(getLocomotive().getAddress(), 
																	lightProperty().getValue(), 
																	false, 
																	false, 
																	false, 
																	false);
	
		communicator.sendCommand(cmd);
	}
}
